/**
 * 针对memset memcpy 切换CPU测试
 * @file cpuAffinity.c
 * @author yeqiang
 * @brief 
 * @version 0.1
 * @date 2022-04-08
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sched.h>
#include <errno.h>

// 10GB
#ifndef BUFF_SIZE
// #define BUFF_SIZE  1073741824
#define BUFF_SIZE  1073741824
#endif

/* Return the UNIX time in microseconds */
long long ustime(void) {
    struct timeval tv;
    long long ust;

    gettimeofday(&tv, NULL);
    ust = ((long long)tv.tv_sec)*1000000;
    ust += tv.tv_usec;
    return ust;
}

int main(int argc, char* argv[]){
    if(argc != 4){
        printf("usage: perf stat ./a.out m n loop\n");
        printf("m: 起始CPU编号，如0\n");
        printf("m: 结束CPU编号，如63\n");
        printf("loop: 循环次数，如100\n");
        return 1;
    }

    int data = 1;
    long long t0, t1;
    float tx, total=0;
    char cmd[64] = {0};
    int m,n,loop;
    m = atoi(argv[1]);
    n = atoi(argv[2]);
    loop = atoi(argv[3]);

    pid_t pid = getpid();
    printf("pid=%d\n", pid);

    cpu_set_t mask;    

    char * srcBuff = (char *)malloc(BUFF_SIZE);
    char * destBuff = (char *)malloc(BUFF_SIZE);
    for(int i = m;i<=n;i++){
        CPU_ZERO(&mask);
        CPU_SET(i, &mask);
        if(sched_setaffinity(0, sizeof(mask), &mask) == -1){
            printf("Set CPU affinity failue, ERROR:%s\n", strerror(errno));
            return -1; 
        }
        printf("CPU%d:", i);

        for(int j = 0;j< loop;j++){
            t0 = ustime();            
            memset(srcBuff, j, BUFF_SIZE);
            memcpy(destBuff, srcBuff, BUFF_SIZE);
            t1 = ustime();
            tx = (t1-t0)/1000000.0f;
            total+=tx;
            printf("%6f,", tx);
            fflush(stdout);
            memset(cmd, 0, sizeof(cmd));
            sprintf(cmd, "numastat -p %d > CPU%d-loop%d 2>&1\n", pid, i, j);
            system(cmd);
        }        
        printf("\n");
    }
    printf("total=%6fs\n", total);

    free(srcBuff);
    free(destBuff);
    return 0;
}